package com.yqyd.common.utils;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.google.common.collect.ImmutableMap;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.*;

/**
 * 微信工具类
 */
public class WechatUtils {
    //公众号请求的地址
    public static String WX_GZH_API = "https://api.weixin.qq.com/cgi-bin/";
    // token
    private static String tokenUrl = "https://api.weixin.qq.com/cgi-bin/token";
    // 手机号授权url
    private static String getuserphonenumberUrl = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=%s";
    // 获取openId
    private static String jscode2sessionUrl = "https://api.weixin.qq.com/sns/jscode2session";

    //通过 URL Link 进入的小程序页面路径，必须是已经发布的小程序存在的页面，不可携带 query 。path 为空时会跳转小程序主页
    private static final String PATH = "path";
    // 携带的参数 a=2
    private static final String QUERY = "query";
    //生成的 URL Link 类型，到期失效：true，永久有效：false
    private static final String IS_EXPIRE = "is_expire";
    //小程序 URL Link 失效类型，失效时间：0，失效间隔天数：1
    private static final String EXPIRE_TYPE = "expire_type";
    //到期失效的URL Link的失效间隔天数。生成的到期失效URL Link在该间隔时间到达前有效。最长间隔天数为365天。expire_type 为 1 必填
    private static final String EXPIRE_INTERVAL = "expire_interval";
    private static final String URL_LINK = "url_link";


    /**
     * 小程序token
     *
     * @param appId
     * @param secret
     * @return
     */
    public static String token(String appId, String secret) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("grant_type", "client_credential");
        params.put("appid", appId);
        params.put("secret", secret);
        JSONObject json = (JSONObject) JSONUtil.parse(HttpUtil.get(tokenUrl, params));
        if (StringUtils.isEmpty(json.getStr("access_token"))) {
            return "";
        }
        return json.getStr("access_token");
    }



    public static JSON sessionData(String jsCode, String appId, String secret) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("appid", appId);
        params.put("secret", secret);
        params.put("js_code", jsCode);
        params.put("grant_type", "authorization_code");
        return JSONUtil.parseObj(HttpUtil.post(jscode2sessionUrl, params));
    }


    public static String Openid(String jsCode, String appId, String secret) {
        JSONObject json = (JSONObject) sessionData(jsCode, appId, secret);
        return json.getStr("openid", "");
    }

    public static JSONObject phonenumber(String code, String access_token) {
        Map<String, Object> requestParam = new HashMap<String, Object>();
        requestParam.put("code", code);
        ResponseEntity<JSONObject> result = new RestTemplate().postForEntity(String.format(getuserphonenumberUrl, access_token), requestParam, JSONObject.class);
        return result.getBody();
    }

    /**
     * 解密工具直接放进去即可
     */
    public static String decryptS5(String encryptedData, String sessionKey, String iv) {
        try {
            byte[] raw = cn.hutool.core.codec.Base64.decode(sessionKey);
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            IvParameterSpec ivParameter = new IvParameterSpec(cn.hutool.core.codec.Base64.decode(iv));
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivParameter);
            byte[] myendicod = cn.hutool.core.codec.Base64.decode(encryptedData);
            byte[] original = cipher.doFinal(myendicod);
            return new String(original, "utf-8");
        } catch (Exception ex) {
            return null;
        }
    }



    private static String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash) {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }


}
